package com.lin.java.tool.oss.storage.engine.aliyun;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import com.lin.java.tool.oss.storage.StorageClientFactory;
import com.lin.java.tool.oss.storage.StorageEngine;
import com.lin.java.tool.general.enums.OssEnum;
import com.lin.java.tool.general.ex.CustomFileException;
import com.lin.java.tool.oss.model.UploadFileData;
import com.lin.java.tool.oss.model.dto.DownloadRespDTO;
import com.lin.java.tool.oss.model.dto.UploadRespDTO;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;

/**
 * @author linjiang
 * @date 2024/7/26
 * @fn
 */
@Slf4j
public class AliyunStorageEngine implements StorageEngine {

    private String bucket;

    private StorageClientFactory<OSS> clientFactory;

    public AliyunStorageEngine(String bucket, StorageClientFactory<OSS> clientFactory) {
        this.bucket = bucket;
        this.clientFactory = clientFactory;
    }

    @Override
    public UploadRespDTO put(UploadFileData uploadFileData) {
        log.info("阿里云对象存储上传。。。。。。。。。。。。");

        if (StrUtil.isEmpty(uploadFileData.getObjectName())) {
            throw new CustomFileException(OssEnum.FILE_FAIL_OBJECTNAME_NOT_EXIST);
        }

        // 构建上传实列
        OSS ossClient = this.clientFactory.getClient();
        try (InputStream inputStream = uploadFileData.getFileStream()) {
            String objectName = uploadFileData.getObjectName();
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, inputStream);
            // 发送上传请求
            ossClient.putObject(putObjectRequest);

            return UploadRespDTO.builder().bucket(bucket).objectName(objectName).build();
        } catch (OSSException oe) {
            log.error("上传文件到阿里云oss异常：{}", oe);
            throw new CustomFileException(OssEnum.FILE_FAIL_UPLOAD.getCode(), String.format("上传文件到阿里云oss异常【%s】", oe.getMessage()));
        } catch (ClientException ce) {
            log.error("阿里云对象连接网络异常：{}", ce);
            throw new CustomFileException(OssEnum.FILE_FAIL_UPLOAD.getCode(), String.format("连接阿里云对象存储服务网络异常【%s】", ce.getMessage()));
        } catch (Exception ex) {
            log.error("阿里云上传异常：{}", ex);
            throw new CustomFileException(OssEnum.FILE_FAIL_UPLOAD);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    @Override
    public DownloadRespDTO get(String objectName) {
        log.info("阿里云对象存储下载。。。。。。。。。。。。");
        OSS ossClient = this.clientFactory.getClient();
        try {
            // 创建GetObjectRequest对象。
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, objectName);
            // ossObject包含文件所在的存储空间名称、文件名称、文件元数据以及一个输入流。
            OSSObject object = ossClient.getObject(getObjectRequest);
            byte[] bytes = IoUtil.readBytes(object.getObjectContent());
            object.close();
            return DownloadRespDTO.builder().bytes(bytes).build();
        } catch (OSSException oe) {
            log.error("阿里云oss下载文件异常：{}", oe);
            throw new CustomFileException(OssEnum.FILE_FAIL_DOWNLOAD.getCode(), String.format("阿里云oss下载文件异常【%s】", oe.getErrorMessage()));
        } catch (ClientException ce) {
            log.error("阿里云对象连接网络异常：{}", ce);
            throw new CustomFileException(OssEnum.FILE_FAIL_UPLOAD.getCode(), String.format("连接阿里云对象存储服务网络异常【%s】", ce.getErrorMessage()));
        } catch (Exception ex) {
            log.error("阿里云下载异常：{}", ex);
            throw new CustomFileException(OssEnum.FILE_FAIL_UPLOAD);
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

}
